package microcredit;

import java.awt.EventQueue;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.logging.LogManager;

import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import microcredit.db.Backup;
import microcredit.db.Factory;
import microcredit.gui.LoadingFrame;
import microcredit.gui.LoginDialog;
import microcredit.gui.MainFrame;
import microcredit.gui.MainFrameController;
import microcredit.gui.plaf.Extensions;
import microcredit.gui.util.ExceptionDialog;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MicroCredit {

	private static final Log LOGGER = LogFactory.getLog(MicroCredit.class);
	
	private static LoadingFrame loading;
	
	public static final String PATH_TO_DB = "db/db";
	
	public static void main(String[] args) throws InterruptedException, InvocationTargetException {
		setupLogging();
		
		// setup parameter
		if (args != null && args.length > 0) {
			String firstParameter = args[0];
			if (firstParameter != null && firstParameter.equals("-external-db")) {
				System.setProperty("eclipselink", "eclipselink.properties");
			}
		}
		
		Locale.setDefault(Locale.ENGLISH);
		JComponent.setDefaultLocale(Locale.ENGLISH);
		
		// init data provider
		
		EventQueue.invokeAndWait(new Runnable() {
			public void run() {
				try {
					Extensions.install();
					loading = new LoadingFrame();
					loading.setLocationRelativeTo(null);
					loading.setVisible(true);
				} catch (Exception e) {
					ExceptionDialog.handleException(null, e);
					System.exit(-1);
				}
			}
		});
		
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				if (!Version.DEBUG) {
					LoginDialog dialog = new LoginDialog();
					dialog.setLocationRelativeTo(loading);
					dialog.setLocation(dialog.getX(), dialog.getY()+100);
					dialog.setVisible(true);
					dialog.toFront();
				}
			}
		});

		
		try {
			Factory.initFactoryNew();
			Factory.getFactory().createEntityManager().close();
		} catch (final Throwable e1) {
			SwingUtilities.invokeAndWait(new Runnable() {
				@Override
				public void run() {
					ExceptionDialog.handleException(loading, e1);
					System.exit(-1);
				}
			});
		}
		try {
			Backup.automaticBackup();
		} catch (Exception e1) {
			LOGGER.error("Backup failed", e1);
			JOptionPane.showMessageDialog(loading, "Backup failed: "+e1.getMessage(), "Backup failed", JOptionPane.WARNING_MESSAGE);
		}
		
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					loading.dispose();
					loading = null;
					MainFrameController controller = new MainFrameController();
					MainFrame frame = new MainFrame(controller);
					frame.setLocationRelativeTo(null);
					frame.setVisible(true);
					frame.toFront();
					frame.requestFocus();
				} catch (Exception e) {
					ExceptionDialog.handleException(loading, e);
				}
			}
		});
	}

	private static void setupLogging() {
		File logFile = new File("config/logging.properties");
		if (logFile.exists()) {
			File logFolder = new File("log");
			if (!logFolder.exists()) {
				logFolder.mkdir();
			}
			try {
				FileInputStream stream = new FileInputStream(logFile);
				LogManager.getLogManager().reset();
				LogManager.getLogManager().readConfiguration(stream);
				stream.close();
			} catch (Exception e){
				// print to console logging configuration was invalid.
				e.printStackTrace();
				LOGGER.error(e.getMessage(),e);
			}
		}
	}
	
}
